package orchestration.businessprocess.model.nodes;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import orchestration.businessprocess.model.BPAnnotation;
import orchestration.businessprocess.model.BPArtifact;
import orchestration.businessprocess.model.BPNodeId;
import orchestration.businessprocess.model.IBPVisitor;

/**
 * Generic node class
 * A node has an id, a name and a type.
 * It can have attached some input, output or annotations
 * @author  <a href="mailto:car.ferrarini@gmail.com">Carlo Ferrarini</a>
 */
public abstract class BPNode{
	public static final int NODE_TYPE_TASK=0;
	public static final int NODE_TYPE_FGW=2;	
	public static final int NODE_TYPE_EGW=6;
	public static final int NODE_TYPE_ST_EV=3;
	public static final int NODE_TYPE_INT_EV=4;
	public static final int NODE_TYPE_END_EV=5;
	public static final int NODE_TYPE_JGW=1;
	public static final int NODE_TYPE_MGW = 7;	

	/**
	 * @uml.property  name="id"
	 * @uml.associationEnd  
	 */
	private BPNodeId id;
	/**
	 * @uml.property  name="name"
	 */
	private String name;
	private int type;
	/**
	 * @uml.property  name="attachedAnnotations"
	 */
	private Map<String,BPAnnotation> attachedAnnotations;
	/**
	 * @uml.property  name="input"
	 */
	private Set<BPArtifact> input;
	/**
	 * @uml.property  name="output"
	 */
	private Set<BPArtifact> output;
	
	BPNode(BPNodeId id,int type,Set<BPArtifact> input,Set<BPArtifact> output) {
		super();
		this.id = id;
		this.type=type;
		this.input=input;
		this.output=output;
		this.attachedAnnotations= new HashMap<String, BPAnnotation>();
	}

	/**
	 * @return
	 * @uml.property  name="id"
	 */
	public BPNodeId getId() {
		return id;
	}

	/**
	 * @param id
	 * @uml.property  name="id"
	 */
	public void setId(BPNodeId id) {
		this.id = id;
	}
	
	/**
	 * @return
	 * @uml.property  name="name"
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name
	 * @uml.property  name="name"
	 */
	public void setName(String name) {
		this.name = name;
	}

	public int getNodeType() {
		return type;
	}

	public abstract void accept(IBPVisitor visitor);

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + type;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		BPNode other = (BPNode) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (type != other.type)
			return false;
		return true;
	}
	
	public BPAnnotation getAnnotation(String annId){
		return attachedAnnotations.get(annId);
	}
	public void attachAnnotation(BPAnnotation annotation){
		attachedAnnotations.put(annotation.getId(), annotation);
	}
	/**
	 * @return
	 * @uml.property  name="attachedAnnotations"
	 */
	public Map<String,? extends BPAnnotation> getAttachedAnnotations() {
		return attachedAnnotations;
	}

	/**
	 * @return
	 * @uml.property  name="input"
	 */
	public Set<BPArtifact> getInput() {
		return input;
	}

	/**
	 * @return
	 * @uml.property  name="output"
	 */
	public Set<BPArtifact> getOutput() {
		return output;
	}
}
